<template>
  <div class="map">
    <div id="map"></div>
    <div class="address">
      <img src="@/assets/img/pos_name_icon.png" alt="" class="icon" />
      <span>{{ state.currLocationName }}</span>
    </div>
    <div @click="addPolygon" class="button add">
      <img src="@/assets/img/button_start.png" alt="" />
      <p>添加测绘</p>
    </div>
    <div @click="del" class="button del">
      <img src="@/assets/img/button_del.png" alt="" />
      <p>删除测绘</p>
    </div>
    <div ref="holderRef" class="holder">
      <div class="get_current button" @click="setCurrentPosMarkPosAndResize">
        <img src="@/assets/img/curr_location.svg" alt="" />
        <p>当前位置</p>
      </div>
    </div>
    <img src="@/assets/img/north_point.png" alt="" class="north_img" />
    <Popup
      @handleActEnd="handleActEnd"
      ref="popupRef"
      :beforeClose="beforeClose"
      :showClose="false"
      :icon="popupIcon"
      :title="titleComp"
      v-model="state.showModal"
      :hasModal="hasModal"
    >
      <Soil
        :position="state.locationName"
        :deviceId="state.deviceId"
        v-if="state.type === 'soil'"
      />
      <Camera
        :position="state.locationName"
        :deviceId="state.deviceId"
        v-if="state.type === 'camera'"
      />
      <Pest
        :position="state.locationName"
        :deviceId="state.deviceId"
        v-if="state.type === 'insect'"
      />
      <Weather
        :position="state.locationName"
        :deviceId="state.deviceId"
        v-if="state.type === 'weather'"
      />
      <Detail
        :position="state.locationName"
        :deviceId="state.deviceId"
        v-if="state.type === 'detail'"
      />
      <Mapping
        ref="mappingRef"
        @getPolygons="getPolygons"
        @toDetail="toDetail"
        @setCurrentPosMarkPos="setCurrentPosMarkPos"
        v-if="state.type === 'add'"
      />
      <Del @getPolygons="getPolygons" v-if="state.type === 'del'"></Del>
    </Popup>
  </div>
</template>

<script setup>
  import {
    onMounted,
    reactive,
    ref,
    watch,
    defineExpose,
    nextTick,
    computed,
  } from 'vue';
  import Camera from '@/components/camera/index.vue';
  import Weather from '@/components/weather/index.vue';
  import Soil from '@/components/soil/index.vue';
  import Pest from '@/components/pest/index.vue';
  import Detail from '@/components/detail/index.vue';
  import Mapping from '@/components/mapping/index.vue';
  import Del from '@/components/del/index.vue';
  import { useRoute } from 'vue-router';
  import {
    initMapState,
    loadMap,
    handlePolygonClick,
    handlePolygonSelect,
    handleCenter,
    mapState,
    clearSelectedIdList,
    isRedirectToDetail,
  } from '@/store/index';
  import injectPermission from '@/utils/wxutil';
  import { $toast } from '@/components/toast';
  import { getPolygonList, getDeviceList, getLocation } from '@/api/map';

  const state = reactive({
    showModal: false,
    title: '',
    type: '',
    deviceId: '',
    locationName: '',
    currLocationName: '',
    /* showModal: true,
  title: '清除测绘',
  type: 'del' */
  });
  const geocode = new T.Geocoder();

  const popupIcon = computed(() => {
    switch (state.type) {
      case 'detail': {
        return require('@/assets/img/detail.png');
      }

      case 'camera': {
        return require('@/assets/img/camera.png');
      }

      case 'weather': {
        return require('@/assets/img/weather.png');
      }

      case 'soil': {
        return require('@/assets/img/soil.png');
      }

      case 'pest': {
        return require('@/assets/img/pest.png');
      }
    }
  });

  const _h = 42;
  const _w = 35;
  const maoIconMap = new Map()
    .set(
      'camera',
      new T.Icon({
        iconUrl: require('@/assets/img/camera_icon.png'),
        iconSize: new T.Point(_w, _h),
        iconAnchor: new T.Point(_w / 2, -_h / 2),
      })
    )
    .set(
      'weather',
      new T.Icon({
        iconUrl: require('@/assets/img/weacher_icon.png'),
        iconSize: new T.Point(_w, _h),
        iconAnchor: new T.Point(_w / 2, -_h / 2),
      })
    )
    .set(
      'soil',
      new T.Icon({
        iconUrl: require('@/assets/img/soil_icon.png'),
        iconSize: new T.Point(_w, _h),
        iconAnchor: new T.Point(_w / 2, -_h / 2),
      })
    )
    .set(
      'insect',
      new T.Icon({
        iconUrl: require('@/assets/img/pest_icon.png'),
        iconSize: new T.Point(_w, _h),
        iconAnchor: new T.Point(_w / 2, -_h / 2),
      })
    );

  let getCurrInterval;
  /* 
  @params: {longitude: string; latitude: string}
*/
  const setCurrentPosMarkPos = params => {
    const setCurr = async () => {
      try {
        let longitude, latitude, accuracy;
        if (!params) {
          let res = await getLocation();
          longitude = res.longitude;
          latitude = res.latitude;
          accuracy = res.accuracy;
        } else {
          longitude = params.longitude;
          latitude = params.latitude;
        }
        /* if (accuracy && accuracy > 10)
        $toast({
          title: '提示',
          text: '当前定位信号差，请移动到开阔地带',
          during: 2000,
          isShowButton: false
        }) */
        const langlat = new T.LngLat(longitude, latitude);
        geocode.getLocation(langlat, res => {
          if (res.getStatus() !== 0)
            return (state.currLocationName = '获取定位失败');
          state.currLocationName = res.getAddress();
        });
        let currPosMark = window.map
          .getOverlays()
          .find(v => v.options.type === 'curr');
        if (!currPosMark) {
          window.map.addOverLay(
            new T.Marker(langlat, {
              icon: new T.Icon({
                iconUrl: require('@/assets/img/curr_icon.png'),
                iconSize: new T.Point(60, 60),
                iconAnchor: new T.Point(30, 30),
              }),
              type: 'curr',
            })
          );
        } else {
          currPosMark.setLngLat(langlat);
        }
        return langlat;
      } catch (error) {
        console.error(error);
      }
    };
    clearInterval(getCurrInterval);
    getCurrInterval = setInterval(setCurr, 1000);
    return setCurr();
  };

  const setCurrentPosMarkPosAndResize = async () => {
    const langlat = await setCurrentPosMarkPos();
    mapState.zoom = 18;
    window.map.centerAndZoom(langlat, mapState.zoom);
  };

  const titleComp = computed(() => {
    switch (state.type) {
      case 'detail': {
        return '详情';
      }
      case 'del': {
        return '清除测绘';
      }
      case 'add': {
        return '添加测绘';
      }
      case 'camera': {
        return '视频监控';
      }
      case 'weather': {
        return '气象信息';
      }
      case 'soil': {
        return '土壤监控';
      }
      case 'insect': {
        return '虫情监测';
      }
      default: {
        return '';
      }
    }
  });

  const mappingRef = ref();

  const holderRef = ref();

  const popupRef = ref();

  const hasModal = computed(() => {
    if (state.type === 'del') return false;
    return true;
  });

  const toDetail = () => {
    state.showModal = true;
    state.type = 'detail';
    handleCenter();
  };

  const showModal = () => {
    state.showModal = true;
  };

  const handleActEnd = () => {
    if (state.showModal) {
      holderRef.value.style.height = `${popupRef.value.$el.children[0].clientHeight}px`;
    } else {
      holderRef.value.style.height = 0;
    }
    setTimeout(() => {
      resize();
    });
  };

  const resize = () => {
    const _c = window.map.getCenter();
    const _z = window.map.getZoom();
    window.map.checkResize();
  };

  const addPolygon = async () => {
    let { accuracy } = await getLocation();
    if (accuracy && accuracy > 10)
      return $toast({
        title: '提示',
        text: '当前定位信号差，请移动到开阔地带',
        during: 2000,
        isShowButton: false,
      });
    showModal();
    state.type = 'add';
    initMapState();
  };

  const del = () => {
    showModal();
    state.type = 'del';
  };

  const getPolygons = async callback => {
    try {
      const { data } = await getPolygonList();
      mapState.totalPolygon = [];
      mapState.siteList = data;
      window.map.clearOverLays();
      for (let v of data) {
        const config = JSON.parse(v.config);
        if (!config.points) continue;
        config.points = config.points.map(
          p => new T.LngLat(p.longitude, p.latitude)
        );
        let polygon = new T.Polygon(config.points, {
          ...config.config,
          id: v.id,
          area: v.area,
        });
        polygon.addEventListener('click', p =>
          handlePolygonClick(p, () => {
            if (state.type === 'del')
              return handlePolygonSelect(p.target.options.id);
            toDetail();
          })
        );
        map.addOverLay(polygon);
        if (isRedirectToDetail(v.id)) {
          setTimeout(() => {
            handlePolygonClick({ target: polygon });
            toDetail();
          });
        }

        mapState.totalPolygon.push(polygon);
      }
      setCurrentPosMarkPos();
      callback && callback();
    } catch (error) {
      console.error(error);
    }
  };

  const getDevices = async () => {
    try {
      const res = await getDeviceList();
      if (
        !!res &&
        !!res.data &&
        !!res.data.records &&
        !!res.data.records.length
      ) {
        res.data.records.map(v => {
          if (!maoIconMap.has(v.useType)) return;
          const marker = new T.Marker(new T.LngLat(v.longitude, v.latitude), {
            icon: maoIconMap.get(v.useType),
          });
          marker.addEventListener('click', target => {
            state.type = v.useType;
            state.deviceId = v.deviceId;
            state.showModal = true;
            state.locationName = v.locationName;
          });
          window.map.addOverLay(marker);
        });
      }
    } catch (error) {
      console.error(error);
    }
  };

  const beforeClose = () => {
    if (mappingRef && mappingRef.value && mappingRef.value.state.isDrawing) {
      $toast({
        title: '提示',
        text: '测绘中，请勿进行其他操作',
        during: 2000,
        isShowButton: false,
      });
      return false;
    }
    state.type = '';
    clearSelectedIdList();
    return true;
  };

  onMounted(async () => {
    try {
      await loadMap('map');
      getPolygons();
      getDevices();
    } catch (error) {
      console.error(error);
    }
  });
</script>

<style lang="scss" scoped>
  .map {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    height: 100%;
    width: 100%;
  }

  #map {
    flex: 1 1 auto;
  }

  .button {
    width: 0.96rem;
    height: 1.47rem;
    background: #ffffff;
    box-shadow: 0rem 0rem 0.2rem 0rem rgba(0, 0, 0, 0.5);
    border-radius: 0.16rem;
    position: fixed;
    right: 0.26rem;
    z-index: 1000;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;

    &.add {
      bottom: 3.77rem;
    }

    &.del {
      bottom: 1.98rem;
    }

    img {
      height: 0.48rem;
      width: 0.48rem;
      margin-bottom: 0.11rem;
    }

    p {
      width: 0.52rem;
      height: 0.56rem;
      font-size: 0.26rem;
      font-family: PingFangSC, PingFang SC;
      font-weight: 400;
      color: #585858;
      line-height: 0.28rem;
    }
  }

  .holder {
    position: relative;
    overflow: visible;

    .get_current {
      position: absolute;
      top: -1.7rem;
      right: 0.26rem;
      background: #ffffff;
      box-shadow: 0rem 0rem 0.2rem 0rem rgba(0, 0, 0, 0.5);
      border-radius: 0.16rem;

      img {
        height: 0.48rem;
        width: 0.48rem;
      }
    }
  }

  .address {
    position: fixed;
    top: 0;
    left: 0;
    z-index: 1000;
    height: 0.68rem;
    background: rgba(0, 0, 0, 0.5);
    width: 100%;
    padding-left: 0.32rem;
    display: flex;
    align-items: center;

    .icon {
      width: 0.28rem;
      height: 0.28rem;
      margin-right: 0.21rem;
    }

    span {
      font-size: 0.28rem;
      font-family: PingFangSC, PingFang SC;
      font-weight: 400;
      color: #ffffff;
      overflow: hidden;
      white-space: nowrap;
      text-overflow: ellipsis;
    }
  }
  .north_img {
    position: fixed;
    z-index: 1000;
    width: 0.6rem;
    height: 1.04rem;
    right: 0.45rem;
    bottom: 5.81rem;
  }
</style>
